package ntv

import (
	"encoding/base64"
	"encoding/hex"
)

// NTV 最小密码应用请求数据结构体，包含名称（Name）、类型（Type）和值（Value）
// Name: 作为键值对中的键（Key）
// Type: 值的类型，可选：base64、hex、raw等。这里内部可以用枚举替代，对外用字符串
type NTV struct {
	ntv       map[string][]byte
	Name      string `json:"Name,omitempty"`
	Type      string `json:"Type,omitempty"`
	valueType ValueType
	Value     interface{} `json:"Value,omitempty"`
	// 内部采用byte数组
	valueByte []byte
	// 其他Json原生数据
	jsonRaw interface{} `json:"-"`
}

type ValueType int

const (
	Raw ValueType = iota
	Hex
	Base64
)

func (c ValueType) String() string {
	switch c {
	case Hex:
		return "Hex"
	case Base64:
		return "Base64"
	}
	return "Raw"
}

// New 创建新的NTV对象
func New(name string, valueType ValueType, value []byte) *NTV {
	return &NTV{
		Name:      name,
		valueType: valueType,
		valueByte: value,
	}
}

// New 创建新的NTV对象
func NewWithRaw(name string, value interface{}) *NTV {
	return &NTV{
		Name:      name,
		valueType: Raw,
		jsonRaw:   value,
	}
}

func (ntv *NTV) Marshal() {
	ntv.Type = ntv.valueType.String()
	ntv.Value = ntv.encode()
}

func (ntv *NTV) encode() (encoded interface{}) {
	if ntv.valueByte != nil {
		switch ntv.valueType {
		case Hex:
			encoded = hex.EncodeToString(ntv.valueByte)
		case Base64:
			encoded = base64.StdEncoding.EncodeToString(ntv.valueByte)
		default:
			encoded = string(ntv.valueByte)
		}
	} else if ntv.jsonRaw != nil && ntv.valueType == Raw {
		return ntv.jsonRaw
	} else {
		return nil
	}
	return encoded
}
